#ifndef ENGINE_H_INCLUDED
#define ENGINE_H_INCLUDED

#include "common.h"
#include <sfml/graphics.hpp>
#include <boost/thread.hpp>

#include <cl/cl.h>

#include <vector>

struct Engine
{

    int screenwidth;
    int screenheight;
    int screendepth;

    sf::RenderWindow window;
    sf::Image screen;

    boost::mutex mut;


    cl_float *clf_screenr;
    cl_float *clf_screeng;
    cl_float *clf_screenb;
    cl_uint *clf_screena;

    //bool cstate;
    cl_uint lframenum;

    cl_float4 *blank;
    cl_float4 *blank_depthindicator;


    cl_mem clfm_screenr;
    cl_mem clfm_screeng;
    cl_mem clfm_screenb;
    cl_mem clfm_screena;

    cl_mem gscreen_rgb;
    cl_mem id_triangles;
    cl_mem light_normals;
    cl_mem uvw_coords;
    cl_mem depth_vanilla;

    cl_mem glights;
    cl_mem glnum;

    cl_mem tcount;

    static cl_mem gtriangles;
    static cl_mem gisdrawbuffer;
    static unsigned int itriangles;
    static cl_mem image3d; ///3d array of 2d textures
    static unsigned int gltscreen_id;
    static unsigned int framebuffer;
    static cl_mem triangleambientcolours;
    static cl_mem atomic_id_buffer;

    static cl_uint *gid_bufferiswritten;
    static cl_uint *gid_bufferisread;

    cl_float4 *cam_rot;
    cl_float4 *cam_pos;

    cl_uint *cl_screenwidth; ///move all memory allocation outside loop
    cl_uint *cl_screenheight;

    static cl_uint *atomic_buffer_read;

    cl_float4 ambientcolour;

    v3d c_pos;

    v3d c_rot;

    sf::Keyboard keyboard;

    std::list<cl_float4> lightpos; ///do list later and etc
    /// W component of lightpos is the lights radius for easy passing to opencl
    std::list<cl_float4> lightcol;
    //std::list<float>     lightrad;

    Engine();
    ~Engine();


    void load(int psw, int psh, int psd, bool fullscr);



    void draw_objects();


    void render();

    void set_ambiance(cl_float, cl_float, cl_float, cl_float brightness);

    void triangle_compile(std::list<triangle>::iterator it, std::list<triangle>::iterator it1);

    void screen_fill(int, int, int, int);

    void add_light(cl_float4 plightposition, cl_float4 plightcolour, float rad); ///lights really need to be allocated within engine so they can be manipulated, and stored by reference
    void add_light(cl_float4 plightposition, cl_float4 plightcolour); ///W COMPONENT MUST BE RADIUS OF PLIGHTPOSITION

    //void rem_light() ///work this out at some point

    void gpush_lights();

    void grem_lights();

    void render_buffers();

    void draw_gobjects_cl();

    void init_glcl();

    void input();

    void tick(); ///do everything

    void fire_objmanager();

};





#endif // ENGINE_H_INCLUDED
